/*-----------------------------------------------------------------------------
	The contents of this file are subject to the Mozilla Public License
	Version 1.1 (the "License"); you may not use this file except in
	compliance with the License. You may obtain a copy of the License at
	http://www.mozilla.org/MPL/
	
	Software distributed under the License is distributed on an "AS IS"
	basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
	License for the specific language governing rights and limitations
	under the License.
	
	The Original Code is Fever Framework code.
	
	The Initial Developer of the Original Code is Romain Ecarnot.
	Portions created by Initial Developer are Copyright (C) 2006
	the Initial Developer. All Rights Reserved.
	
	Contributor(s):
	
	Unless required by applicable law or agreed to in writing, software
	distributed under the License is distributed on an "AS IS" BASIS,
	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	See the License for the specific language governing permissions and
	limitations under the License.
-----------------------------------------------------------------------------*/

import com.bourre.data.collections.Map;
import com.bourre.structures.Point;
import com.bourre.structures.Rectangle;

import fever.app.context.abstract.ContextContainer;
import fever.app.context.abstract.IContextContainer;
import fever.app.context.browser.ClientBrowser;
import fever.app.local.Localisation;
import fever.commands.JSCommand;
import fever.commands.JSMethodName;
import fever.core.ApplicationState;
import fever.core.FeverRoot;
import fever.events.ApplicationEvent;
import fever.Fever;

/**
 * Builds a <strong>Browser container</strong> for application.
 * 
 * @author Romain Ecarnot
 */
class fever.app.context.browser.BrowserContainer extends ContextContainer 
	implements IContextContainer
{
	//-------------------------------------------------------------------------
	// Private properties
	//-------------------------------------------------------------------------
	
	private static var _initialized : Boolean = false;
	
	private static var setTitleMETHOD : JSMethodName = new JSMethodName( 'setTitle' );	private static var getTitleMETHOD : JSMethodName = new JSMethodName( 'getTitle' );	private static var setLocationMETHOD : JSMethodName = new JSMethodName( 'setLocation' );	private static var getLocationMETHOD : JSMethodName = new JSMethodName( 'getLocation' );
	private static var setSizeMETHOD : JSMethodName = new JSMethodName( 'setSize' );
	private static var getSizeMETHOD : JSMethodName = new JSMethodName( 'getSize' );	private static var getURLMETHOD : JSMethodName = new JSMethodName( 'getURL' );
	
	private var _setTitle : JSCommand;	private var _getTitle : JSCommand;	private var _setLocation : JSCommand;	private var _getLocation : JSCommand;	private var _setSize : JSCommand;	private var _getURL : JSCommand;
	
	private var _browser : ClientBrowser;
	private var _displayState : Boolean;
	
	private var _caption : String;
	private var _args : Map;
	
		
	//-------------------------------------------------------------------------
	// Public API
	//-------------------------------------------------------------------------
	
	/**
	 * Constructor.
	 */
	public function BrowserContainer()
	{
		super();
		
		_init();
	}
	
	/** 
	 * Set the container title.
	 */
	public function setTitle(  newtitle : String  ) : Void 
	{
		_caption = newtitle;
		_setTitle.call( newtitle );
	}
	
	/** 
	 * Returns the container title.
	 */
	public function getTitle() : String
	{
		_caption = _getTitle.call().toString();
		
		if( !_caption )
		{
			var tx : TextField = FeverRoot.LEVEL[ '_title' ];
			_caption = ( tx != undefined ) ? tx.text : '';
		}
		return _caption;
	}
	
	/** 
	 * Set the container position.
	 */
	public function setLocation( x : Number, y : Number ) : Void
	{
		_setLocation.call( x, y );
	}
	
	/** 
	 * Returns the container title.
	 */
	public function getLocation() : Point
	{
		var r : Object = _getLocation.call();
		return new Point( r.x, r.y );
	}
	
	/** 
	 * Set the container size.
	 */
	public function setSize( width : Number, height : Number ) : Void
	{
		_setSize.call( width, height );
	}
	
	/** 
	 * Returns the container title.
	 */
	public function getSize() : Rectangle
	{
		return new Rectangle( Stage.width, Stage.height, 0, 0 );
	}
	
	/**
	 * 	Sets current application in fullscreen mode if passed-in {@code enabled} 
	 * 	is {@code true}, or in normal mode if {@code false}.
	 * 	
	 * 	<p>A {@link fever.events.StageEvent#STAGE_STATE_CHANGED} event is 
	 * 	broadcasted when mode changed.
	 * 	
	 * 	<p>Application argument must be passed to flash object to enable fullscreen 
	 * 	feature.
	 * 	
	 * 	{@code
	 * 	  var o = new SWFObject( "swfFile.swf", "fswf", "800", "600", "8", "#000000" );
	 *	  o.addParam( "allowFullScreen", "true" );
	 *	  o.write("flashcontent");
	 * 	}
	 * 	
	 * 	<p>Only available with Player version > 9.0.18.
	 */
	public function setFullScreenMode( enabled : Boolean ) : Void
	{
		if( _displayState != enabled )
		{
			if( Fever.client.player.isCompliant( 9,0,18 ) )
			{
				Stage['displayState'] = ( enabled ) ? 'fullScreen' : 'normal';
			}
			else Fever.dialog.alert( Localisation.getResource( 'fever:common.fullscreenError' ) );
		}
	}
	
	/**
	 * Indicates if current application is on fullscreen mode {@code true} or 
	 * in normal mode {@code false}.
	 */
	public function isFullScreen() : Boolean
	{
		return _displayState;	
	}
	
	/** 
	 * Returns application argument associated with {@code id} ID.
	 */
	public function getArgument( id ) : String
	{
		if( _args.containsKey( id ) ) return _args.get( id );
		else return _root[id];	
	}
	
	
	//-------------------------------------------------------------------------
	// Private implementation
	//-------------------------------------------------------------------------
	
	private function _init() : Void
	{
		_displayState = false;
		
		_browser = new ClientBrowser( this );
		_args = new Map();
		
		Stage.addListener( this );
		
		_initJSCommand();
		_parseArguments();
	}
	
	private function onResize() : Void
	{
		Fever.application.broadcastEvent( new ApplicationEvent( ApplicationEvent.onResizeEVENT ) );	
	}
	
	private function _parseArguments() : Void
	{
		var url : String = String( _getURL.call() );
		
		if( url.length > 1 )
		{
			url = url.substr( 1 );
			var pair : Array = url.split( '&' );
			var pairLength : Number = pair.length;
			
			for( var i : Number = 0; i < pairLength; i++ )
			{
				var assos : Array = pair[i].split( '=' );
				_args.put( unescape( assos[0] ), unescape( assos[1] ) );	
			}
		}
	}
	
	private function _initJSCommand() : Void
	{
		if( !_initialized )
		{
			_setTitle = new JSCommand( 
				setTitleMETHOD,
				"( newtitle ){	document.title = newtitle; }"
			);
			
			_getTitle = new JSCommand( 
				getTitleMETHOD,
				"(){ return document.title; }"
			);
			
			_setLocation = new JSCommand(
				setLocationMETHOD,
				"( x, y ){ window.moveTo( x, y );}"
			);
			
			var getLoc : String = "";
			getLoc += "(){";
			getLoc += ( _browser.isIE() )
				? "return { x : window.screenLeft, y : window.screenTop };"
				: "return { x : window.screenX, y : window.screenY };";
			getLoc += "}";
			_getLocation = new JSCommand( getLocationMETHOD, getLoc );
			
			_setSize = new JSCommand(
				setSizeMETHOD,
				"( w, h ){ window.resizeTo( w, h ); }"
			);
			
			_getURL = new JSCommand(
				getURLMETHOD,
				"(){ return window.location.search;}"
			);
			
			_initialized = true;
		}
	}
	
	private function onFullScreen( b : Boolean ) : Void
	{
		_displayState = b;
		
		Fever.application.broadcastEvent( 
			new ApplicationEvent( 
				ApplicationEvent.onStateChangeEVENT, 
				( b ) ? ApplicationState.FULLSCREEN : ApplicationState.NORMAL
			 ) 
		);
	}
	
}